﻿
namespace SistemaLogistica.DataAccess
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Common;
    using SistemaLogistica.Business.Entities;

    public class OrdenCompraData : BaseDataAccess
    {
        private OrdenCompraData() { }

        private readonly static OrdenCompraData instancia = new OrdenCompraData();

        public static OrdenCompraData Instancia
        {
            get { return instancia; }
        }

        public List<OrdenCompra> Listar()
        {
            List<OrdenCompra> ordenesCompra = new List<OrdenCompra>();
            DbCommand command = db.GetStoredProcCommand("GetAllFromOrdenCompra");

            using (IDataReader dr = db.ExecuteReader(command))
            {
                while (dr.Read())
                {
                    ordenesCompra.Add(new OrdenCompra
                    {
                        IdOrdenCompra = dr.GetInt32(dr.GetOrdinal("IdOrdenCompra")),
                        Proveedor = new Proveedor { IdProveedor = dr.GetInt32(dr.GetOrdinal("IdProveedor")) },
                        Empleados = new Empleados { IdEmpleado = dr.GetInt16(dr.GetOrdinal("IdEmpleado")) },
                        Fecha = dr.GetDateTime(dr.GetOrdinal("FechaCompra")),
                        Estado = dr.GetBoolean(dr.GetOrdinal("Estado")),
                        Descripcion = dr.GetString(dr.GetOrdinal("Descripcion")),
                        OrdenPedido = new OrdenPedido
                        {
                            IdOrdenPedido = dr.GetInt32(dr.GetOrdinal("IdOrdenPedido")),
                            Pedido = new Pedido
                            {
                                IdPedido = dr.GetInt32(dr.GetOrdinal("IdPedido")),
                                Area = new Area
                                {
                                    IdArea = dr.GetInt32(dr.GetOrdinal("IdArea")),
                                    Nombre = dr.GetString(dr.GetOrdinal("Nombre"))
                                }
                            }
                        }
                    });
                }
            }
            return ordenesCompra;
        }

        public List<OrdenCompra> BuscarPorFechas(DateTime desde, DateTime hasta)
        {
            List<OrdenCompra> ordenesCompra = new List<OrdenCompra>();
            DbCommand command = db.GetStoredProcCommand("SearchOrdenCompra");
            db.AddInParameter(command, "desde", DbType.DateTime, desde);
            db.AddInParameter(command, "hasta", DbType.DateTime, hasta);

            using (IDataReader dr = db.ExecuteReader(command))
            {
                while (dr.Read())
                {
                    ordenesCompra.Add(new OrdenCompra
                    {
                        IdOrdenCompra = dr.GetInt32(dr.GetOrdinal("IdOrdenCompra")),
                        Proveedor = new Proveedor { IdProveedor = dr.GetInt32(dr.GetOrdinal("IdProveedor")) },
                        Empleados = new Empleados { IdEmpleado = dr.GetInt16(dr.GetOrdinal("IdEmpleado")) },
                        Fecha = dr.GetDateTime(dr.GetOrdinal("FechaCompra")),
                        Estado = dr.GetBoolean(dr.GetOrdinal("Estado")),
                        Descripcion = dr.GetString(dr.GetOrdinal("Descripcion")),
                        OrdenPedido = new OrdenPedido
                        {
                            IdOrdenPedido = dr.GetInt32(dr.GetOrdinal("IdOrdenPedido")),
                            Pedido = new Pedido
                            {
                                IdPedido = dr.GetInt32(dr.GetOrdinal("IdPedido")),
                                Area = new Area
                                {
                                    IdArea = dr.GetInt32(dr.GetOrdinal("IdArea")),
                                    Nombre = dr.GetString(dr.GetOrdinal("Nombre"))
                                }
                            }
                        }
                    });
                }
            }
            return ordenesCompra;
        }

        public OrdenCompra ObtenerPorID(int ordenCompraID)
        {
            OrdenCompra ordenCompra = null;
            DbCommand command = db.GetStoredProcCommand("GetOrdenCompraByIdOrdenCompra");
            db.AddInParameter(command, "idOrdenCompra", DbType.Int32, ordenCompraID);
             
            using (IDataReader dr = db.ExecuteReader(command))
            {
                while (dr.Read())
                {
                    ordenCompra = new OrdenCompra
                    {
                        IdOrdenCompra = dr.GetInt32(dr.GetOrdinal("IdOrdenCompra")),
                        Proveedor = ProveedorData.Instancia.ObtenerPorID(dr.GetInt32(dr.GetOrdinal("IdProveedor"))),
                        Empleados = new Empleados { IdEmpleado = dr.GetInt16(dr.GetOrdinal("IdEmpleado")) },
                        Fecha = dr.GetDateTime(dr.GetOrdinal("FechaCompra")),
                        Estado = dr.GetBoolean(dr.GetOrdinal("Estado")),
                        Descripcion = dr.GetString(dr.GetOrdinal("Descripcion")),
                        OrdenPedido = OrdenPedidoData.Instancia.ObtenerPorID(dr.GetInt32(dr.GetOrdinal("IdOrdenPedido")))
                    };
                    ordenCompra.Detalle = DetalleOrdenCompraData.Instancia.ListarPorOrdenCompra(ordenCompraID, ordenCompra.OrdenPedido.TipoOrdenPedido);
                }
            }
            return ordenCompra;
        }

        public void Registrar(OrdenCompra ordenCompra)
        {
            using (DbConnection conection = db.CreateConnection())
            {
                conection.Open();
                using (DbTransaction transaction = conection.BeginTransaction())
                {
                    try
                    {
                        // INSERTAR ORDEN DE COMPRA

                        DbCommand cmdOrdenCompra = db.GetStoredProcCommand("InsertOrdenCompra");
                        db.AddInParameter(cmdOrdenCompra, "descripcion", DbType.String, ordenCompra.Descripcion);
                        db.AddInParameter(cmdOrdenCompra, "estado", DbType.Boolean, false);
                        db.AddInParameter(cmdOrdenCompra, "fechaCompra", DbType.DateTime, ordenCompra.Fecha);
                        db.AddInParameter(cmdOrdenCompra, "idEmpleado", DbType.Int16, ordenCompra.Empleados.IdEmpleado);
                        db.AddOutParameter(cmdOrdenCompra, "idOrdenCompra", DbType.Int32, 11);
                        db.AddInParameter(cmdOrdenCompra, "idOrdenPedido", DbType.Int32, ordenCompra.OrdenPedido.IdOrdenPedido);
                        db.AddInParameter(cmdOrdenCompra, "idProveedor", DbType.Int32, ordenCompra.Proveedor.IdProveedor);

                        int result = db.ExecuteNonQuery(cmdOrdenCompra, transaction);
                        if (result == 0) throw new Exception("Error al Insertar Orden Compra.");

                        int idOrdenCompra = Convert.ToInt32(db.GetParameterValue(cmdOrdenCompra, "idOrdenCompra"));

                        // INSERTAR DETALLE DE ORDEN DE COMPRA

                        DbCommand cmdDetalleOrden = db.GetStoredProcCommand("InsertDetalleOrdenCompra");
                        db.AddInParameter(cmdDetalleOrden, "cantidad", DbType.Decimal);
                        db.AddInParameter(cmdDetalleOrden, "idBien", DbType.Int32);
                        db.AddInParameter(cmdDetalleOrden, "idOrdenCompra", DbType.Int32);
                        db.AddInParameter(cmdDetalleOrden, "monto", DbType.Currency);

                        DbCommand cmdBien = null;

                        foreach (DetalleOrdenCompra d in ordenCompra.Detalle)
                        {
                            int idBien = d.Bien.IdBien;
                            if (idBien == 0)
                            {
                                cmdBien = db.GetStoredProcCommand("InsertBien");
                                db.AddInParameter(cmdBien, "descripcion", DbType.String, d.Bien.Descripcion);
                                db.AddInParameter(cmdBien, "estado", DbType.Int32, d.Bien.Estado);
                                db.AddOutParameter(cmdBien, "idBien", DbType.Int32, 11);
                                db.AddInParameter(cmdBien, "idUnidadMedida", DbType.Int32, d.Bien.UnidadMedidia.IdUnidadMedida);
                                db.AddInParameter(cmdBien, "nombre", DbType.String, d.Bien.Nombre);
                                db.AddInParameter(cmdBien, "precio", DbType.Currency, d.Bien.Precio);
                                db.AddInParameter(cmdBien, "stockActual", DbType.Decimal, 0);
                                db.AddInParameter(cmdBien, "stockMinimo", DbType.Decimal, 0);
                               
                                result = db.ExecuteNonQuery(cmdBien, transaction);
                                if (result == 0) throw new Exception("Error al Insertar Bien.");

                                idBien = Convert.ToInt32(db.GetParameterValue(cmdBien, "idBien"));

                                Vehiculo vehiculo = d.Bien as Vehiculo;
                                if (vehiculo != null)
                                {
                                    cmdBien = db.GetStoredProcCommand("InsertVehiculo");
                                    db.AddInParameter(cmdBien, "idBien", DbType.Int32, idBien);
                                    db.AddInParameter(cmdBien, "marca", DbType.String, vehiculo.Marca);
                                    db.AddInParameter(cmdBien, "modelo", DbType.String, vehiculo.Modelo);
                                    db.AddInParameter(cmdBien, "nroPlaca", DbType.String, vehiculo.NroPlaca);
                                    db.AddInParameter(cmdBien, "tipoVehiculo", DbType.Int32, vehiculo.TipoVehiculo);
                                    
                                    result = db.ExecuteNonQuery(cmdBien, transaction);
                                    if (result == 0) throw new Exception("Error al Insertar Vehículo.");

                                    cmdBien = db.GetStoredProcCommand("InsertVehiculoPropio");
                                    db.AddInParameter(cmdBien, "fechaCompra", DbType.DateTime, ordenCompra.Fecha);
                                    db.AddInParameter(cmdBien, "idBien", DbType.Int32, idBien);
                                    db.AddOutParameter(cmdBien, "idVehiculoPropio", DbType.Int32, 11);
                                    db.AddInParameter(cmdBien, "precio", DbType.Currency, d.Bien.Precio);
                                    db.AddInParameter(cmdBien, "tarjetaPropiedad", DbType.String, string.Empty);
                                    
                                    result = db.ExecuteNonQuery(cmdBien, transaction);
                                    if (result == 0) throw new Exception("Error al Insertar Vehículo Propio.");
                                }
                                else 
                                {
                                    Telefono telefono = d.Bien as Telefono;
                                    if (telefono != null)
                                    {
                                        cmdBien = db.GetStoredProcCommand("InsertTelefono");
                                        db.AddInParameter(cmdBien, "idBien", DbType.Int32, idBien);
                                        db.AddInParameter(cmdBien, "marca", DbType.String, telefono.Marca);
                                        db.AddInParameter(cmdBien, "modelo", DbType.String, telefono.Modelo);
                                        db.AddInParameter(cmdBien, "nroCelular", DbType.String, telefono.NroCelular);
                                        db.AddInParameter(cmdBien, "tipoCelular", DbType.String, telefono.TipoCelular);

                                        result = db.ExecuteNonQuery(cmdBien, transaction);
                                        if (result == 0) throw new Exception("Error al Insertar Telefono.");
                                    }
                                }
                            }
                            else
                            {
                                cmdBien = db.GetStoredProcCommand("UpdateBien");
                                db.AddInParameter(cmdBien, "descripcion", DbType.String, d.Bien.Descripcion);
                                db.AddInParameter(cmdBien, "estado", DbType.Int32, d.Bien.Estado);
                                db.AddInParameter(cmdBien, "idBien", DbType.Int32, idBien);
                                db.AddInParameter(cmdBien, "idUnidadMedida", DbType.Int32, d.Bien.UnidadMedidia.IdUnidadMedida);
                                db.AddInParameter(cmdBien, "nombre", DbType.String, d.Bien.Nombre);
                                db.AddInParameter(cmdBien, "precio", DbType.Currency, d.Bien.Precio);
                                db.AddInParameter(cmdBien, "stockActual", DbType.Decimal, d.Bien.StockActual);
                                db.AddInParameter(cmdBien, "stockMinimo", DbType.Decimal, d.Bien.StockMinimo);
                                
                                result = db.ExecuteNonQuery(cmdBien, transaction);
                                if (result == 0) throw new Exception("Error al Actualizar Bien.");

                                Vehiculo vehiculo = d.Bien as Vehiculo;
                                if (vehiculo != null)
                                {
                                    cmdBien = db.GetStoredProcCommand("UpdateVehiculo");
                                    db.AddInParameter(cmdBien, "idBien", DbType.Int32, idBien);
                                    db.AddInParameter(cmdBien, "marca", DbType.String, vehiculo.Marca);
                                    db.AddInParameter(cmdBien, "modelo", DbType.String, vehiculo.Modelo);
                                    db.AddInParameter(cmdBien, "nroPlaca", DbType.String, vehiculo.NroPlaca);
                                    db.AddInParameter(cmdBien, "tipoVehiculo", DbType.Int32, vehiculo.TipoVehiculo);

                                    result = db.ExecuteNonQuery(cmdBien, transaction);
                                    if (result == 0) throw new Exception("Error al Actualizar Vehículo.");
                                }
                                else
                                {
                                    Telefono telefono = d.Bien as Telefono;
                                    if (telefono != null)
                                    {
                                        cmdBien = db.GetStoredProcCommand("UpdateTelefono");
                                        db.AddInParameter(cmdBien, "idBien", DbType.Int32, idBien);
                                        db.AddInParameter(cmdBien, "marca", DbType.String, telefono.Marca);
                                        db.AddInParameter(cmdBien, "modelo", DbType.String, telefono.Modelo);
                                        db.AddInParameter(cmdBien, "nroCelular", DbType.String, telefono.NroCelular);
                                        db.AddInParameter(cmdBien, "tipoCelular", DbType.String, telefono.TipoCelular);

                                        result = db.ExecuteNonQuery(cmdBien, transaction);
                                        if (result == 0) throw new Exception("Error al Actualizar Telefono.");
                                    }
                                }
                            }

                            db.SetParameterValue(cmdDetalleOrden, "cantidad", d.Cantidad);
                            db.SetParameterValue(cmdDetalleOrden, "idBien", idBien);
                            db.SetParameterValue(cmdDetalleOrden, "idOrdenCompra", idOrdenCompra);
                            db.SetParameterValue(cmdDetalleOrden, "monto", d.Monto);
                            
                            result = db.ExecuteNonQuery(cmdDetalleOrden, transaction);
                            if (result == 0) throw new Exception("Error al Insertar Detalle de Orden de Compra.");
                        }

                        // ACTUALIZAR ESTADO DE ATENCION DE ORDEN DE PEDIDO

                        DbCommand cmdOPedido = db.GetStoredProcCommand("UpdateEstadoOrdenPedido");

                        db.AddInParameter(cmdOPedido, "idOrdenCompra", DbType.Int32, ordenCompra.OrdenPedido.IdOrdenPedido);
                        db.AddInParameter(cmdOPedido, "estado", DbType.Boolean, true);

                        result = db.ExecuteNonQuery(cmdOPedido, transaction);
                        if (result == 0) throw new Exception("Error al Actualizar Estado de Orden de Pedido.");

                        transaction.Commit();
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        throw ex;
                    }
                }
            }
        }

        public void Actualizar(OrdenCompra ordenCompra)
        {
            using (DbConnection conection = db.CreateConnection())
            {
                conection.Open();
                using (DbTransaction transaction = conection.BeginTransaction())
                {
                    try
                    {
                        int result = 0;

                        // ELIMINAR ANTIGUO DETALLE DE ORDEN DE COMPRA

                        List<DetalleOrdenCompra> detalle = DetalleOrdenCompraData.Instancia.ListarPorOrdenCompra(ordenCompra.IdOrdenCompra);
                        DbCommand cmdDetalleOrdenA = db.GetStoredProcCommand("DeleteDetalleOrdenCompra");
                        db.AddInParameter(cmdDetalleOrdenA, "idBien", DbType.Int32);
                        db.AddInParameter(cmdDetalleOrdenA, "idOrdenCompra", DbType.Int32);
                        db.AddInParameter(cmdDetalleOrdenA, "cantidad", DbType.Decimal);

                        foreach (DetalleOrdenCompra d in detalle)
                        {
                            db.SetParameterValue(cmdDetalleOrdenA, "idBien", d.Bien.IdBien);
                            db.SetParameterValue(cmdDetalleOrdenA, "idOrdenCompra", ordenCompra.IdOrdenCompra);
                            db.SetParameterValue(cmdDetalleOrdenA, "cantidad", d.Cantidad);
                            
                            result = db.ExecuteNonQuery(cmdDetalleOrdenA, transaction);
                            if (result == 0) throw new Exception("Error al Eliminar Detalle de Orden de Compra.");
                        }

                        // ACTUALIZAR ORDEN DE COMPRA

                        DbCommand cmdOrdenCompra = db.GetStoredProcCommand("UpdateOrdenCompra");
                        db.AddInParameter(cmdOrdenCompra, "descripcion", DbType.String, ordenCompra.Descripcion);
                        db.AddInParameter(cmdOrdenCompra, "estado", DbType.Boolean, false);
                        db.AddInParameter(cmdOrdenCompra, "fechaCompra", DbType.DateTime, ordenCompra.Fecha);
                        db.AddInParameter(cmdOrdenCompra, "idEmpleado", DbType.Int16, ordenCompra.Empleados.IdEmpleado);
                        db.AddInParameter(cmdOrdenCompra, "idOrdenCompra", DbType.Int32, ordenCompra.IdOrdenCompra);
                        db.AddInParameter(cmdOrdenCompra, "idOrdenPedido", DbType.Int32, ordenCompra.OrdenPedido.IdOrdenPedido);
                        db.AddInParameter(cmdOrdenCompra, "idProveedor", DbType.Int32, ordenCompra.Proveedor.IdProveedor);

                        result = db.ExecuteNonQuery(cmdOrdenCompra, transaction);
                        if (result == 0) throw new Exception("Error al Actualizar Orden Compra.");

                        // INSERTAR DETALLE DE ORDEN DE COMPRA

                        DbCommand cmdDetalleOrden = db.GetStoredProcCommand("InsertDetalleOrdenCompra");
                        db.AddInParameter(cmdDetalleOrden, "cantidad", DbType.Decimal);
                        db.AddInParameter(cmdDetalleOrden, "idBien", DbType.Int32);
                        db.AddInParameter(cmdDetalleOrden, "idOrdenCompra", DbType.Int32);
                        db.AddInParameter(cmdDetalleOrden, "monto", DbType.Currency);

                        DbCommand cmdBien = null;

                        foreach (DetalleOrdenCompra d in ordenCompra.Detalle)
                        {
                            int idBien = d.Bien.IdBien;
                            if (idBien == 0)
                            {
                                cmdBien = db.GetStoredProcCommand("InsertBien");
                                db.AddInParameter(cmdBien, "descripcion", DbType.String, d.Bien.Descripcion);
                                db.AddInParameter(cmdBien, "estado", DbType.Int32, d.Bien.Estado);
                                db.AddOutParameter(cmdBien, "idBien", DbType.Int32, 11);
                                db.AddInParameter(cmdBien, "idUnidadMedida", DbType.Int32, d.Bien.UnidadMedidia.IdUnidadMedida);
                                db.AddInParameter(cmdBien, "nombre", DbType.String, d.Bien.Nombre);
                                db.AddInParameter(cmdBien, "precio", DbType.Currency, d.Bien.Precio);
                                db.AddInParameter(cmdBien, "stockActual", DbType.Decimal, 0);
                                db.AddInParameter(cmdBien, "stockMinimo", DbType.Decimal, 0);
                               
                                result = db.ExecuteNonQuery(cmdBien, transaction);
                                if (result == 0) throw new Exception("Error al Insertar Bien.");

                                idBien = Convert.ToInt32(db.GetParameterValue(cmdBien, "idBien"));

                                Vehiculo vehiculo = d.Bien as Vehiculo;
                                if (vehiculo != null)
                                {
                                    cmdBien = db.GetStoredProcCommand("InsertVehiculo");
                                    db.AddInParameter(cmdBien, "idBien", DbType.Int32, idBien);
                                    db.AddInParameter(cmdBien, "marca", DbType.String, vehiculo.Marca);
                                    db.AddInParameter(cmdBien, "modelo", DbType.String, vehiculo.Modelo);
                                    db.AddInParameter(cmdBien, "nroPlaca", DbType.String, vehiculo.NroPlaca);
                                    db.AddInParameter(cmdBien, "tipoVehiculo", DbType.Int32, vehiculo.TipoVehiculo);

                                    result = db.ExecuteNonQuery(cmdBien, transaction);
                                    if (result == 0) throw new Exception("Error al Insertar Vehículo.");

                                    cmdBien = db.GetStoredProcCommand("InsertVehiculoPropio");
                                    db.AddInParameter(cmdBien, "fechaCompra", DbType.DateTime, ordenCompra.Fecha);
                                    db.AddInParameter(cmdBien, "idBien", DbType.Int32, idBien);
                                    db.AddOutParameter(cmdBien, "idVehiculoPropio", DbType.Int32, 11);
                                    db.AddInParameter(cmdBien, "precio", DbType.Currency, d.Bien.Precio);
                                    db.AddInParameter(cmdBien, "tarjetaPropiedad", DbType.String, string.Empty);

                                    result = db.ExecuteNonQuery(cmdBien, transaction);
                                    if (result == 0) throw new Exception("Error al Insertar Vehículo Propio.");
                                }
                                else
                                {
                                    Telefono telefono = d.Bien as Telefono;
                                    if (telefono != null)
                                    {
                                        cmdBien = db.GetStoredProcCommand("InsertTelefono");
                                        db.AddInParameter(cmdBien, "idBien", DbType.Int32, idBien);
                                        db.AddInParameter(cmdBien, "marca", DbType.String, telefono.Marca);
                                        db.AddInParameter(cmdBien, "modelo", DbType.String, telefono.Modelo);
                                        db.AddInParameter(cmdBien, "nroCelular", DbType.String, telefono.NroCelular);
                                        db.AddInParameter(cmdBien, "tipoCelular", DbType.String, telefono.TipoCelular);

                                        result = db.ExecuteNonQuery(cmdBien, transaction);
                                        if (result == 0) throw new Exception("Error al Insertar Telefono.");
                                    }
                                }
                            }
                            else
                            {
                                cmdBien = db.GetStoredProcCommand("UpdateBien");
                                db.AddInParameter(cmdBien, "descripcion", DbType.String, d.Bien.Descripcion);
                                db.AddInParameter(cmdBien, "estado", DbType.Int32, d.Bien.Estado);
                                db.AddInParameter(cmdBien, "idBien", DbType.Int32, idBien);
                                db.AddInParameter(cmdBien, "idUnidadMedida", DbType.Int32, d.Bien.UnidadMedidia.IdUnidadMedida);
                                db.AddInParameter(cmdBien, "nombre", DbType.String, d.Bien.Nombre);
                                db.AddInParameter(cmdBien, "precio", DbType.Currency, d.Bien.Precio);
                                db.AddInParameter(cmdBien, "stockActual", DbType.Decimal, d.Bien.StockActual);
                                db.AddInParameter(cmdBien, "stockMinimo", DbType.Decimal, d.Bien.StockMinimo);
                                
                                result = db.ExecuteNonQuery(cmdBien, transaction);
                                if (result == 0) throw new Exception("Error al Actualizar Bien.");

                                Vehiculo vehiculo = d.Bien as Vehiculo;
                                if (vehiculo != null)
                                {
                                    cmdBien = db.GetStoredProcCommand("UpdateVehiculo");
                                    db.AddInParameter(cmdBien, "idBien", DbType.Int32, idBien);
                                    db.AddInParameter(cmdBien, "marca", DbType.String, vehiculo.Marca);
                                    db.AddInParameter(cmdBien, "modelo", DbType.String, vehiculo.Modelo);
                                    db.AddInParameter(cmdBien, "nroPlaca", DbType.String, vehiculo.NroPlaca);
                                    db.AddInParameter(cmdBien, "tipoVehiculo", DbType.Int32, vehiculo.TipoVehiculo);

                                    result = db.ExecuteNonQuery(cmdBien, transaction);
                                    if (result == 0) throw new Exception("Error al Actualizar Vehículo.");
                                }
                                else
                                {
                                    Telefono telefono = d.Bien as Telefono;
                                    if (telefono != null)
                                    {
                                        cmdBien = db.GetStoredProcCommand("UpdateTelefono");
                                        db.AddInParameter(cmdBien, "idBien", DbType.Int32, idBien);
                                        db.AddInParameter(cmdBien, "marca", DbType.String, telefono.Marca);
                                        db.AddInParameter(cmdBien, "modelo", DbType.String, telefono.Modelo);
                                        db.AddInParameter(cmdBien, "nroCelular", DbType.String, telefono.NroCelular);
                                        db.AddInParameter(cmdBien, "tipoCelular", DbType.String, telefono.TipoCelular);

                                        result = db.ExecuteNonQuery(cmdBien, transaction);
                                        if (result == 0) throw new Exception("Error al Actualizar Telefono.");
                                    }
                                }
                            }

                            db.SetParameterValue(cmdDetalleOrden, "cantidad", d.Cantidad);
                            db.SetParameterValue(cmdDetalleOrden, "idBien", idBien);
                            db.SetParameterValue(cmdDetalleOrden, "idOrdenCompra", ordenCompra.IdOrdenCompra);
                            db.SetParameterValue(cmdDetalleOrden, "monto", d.Monto);
                            
                            result = db.ExecuteNonQuery(cmdDetalleOrden, transaction);
                            if (result == 0) throw new Exception("Error al Insertar Detalle de Orden de Compra.");
                        }

                        // ACTUALIZAR ESTADO DE ATENCION DE ORDEN DE PEDIDO

                        DbCommand cmdOPedido = db.GetStoredProcCommand("UpdateEstadoOrdenPedido");

                        db.AddInParameter(cmdOPedido, "idOrdenCompra", DbType.Int32, ordenCompra.OrdenPedido.IdOrdenPedido);
                        db.AddInParameter(cmdOPedido, "estado", DbType.Boolean, true);

                        result = db.ExecuteNonQuery(cmdOPedido, transaction);
                        if (result == 0) throw new Exception("Error al Actualizar Estado de Orden de Pedido.");

                        transaction.Commit();
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        throw ex;
                    }
                }
            }
        }

        public void Eliminar(int idOrdenCompra)
        {
            using (DbConnection conection = db.CreateConnection())
            {
                conection.Open();
                using (DbTransaction transaction = conection.BeginTransaction())
                {
                    try
                    {
                        int result = 0;
                        OrdenCompra ordenCompra = ObtenerPorID(idOrdenCompra);

                        // ELIMINAR ANTIGUO DETALLE DE ORDEN DE COMPRA

                        DbCommand cmdDetalleOrdenA = db.GetStoredProcCommand("DeleteDetalleOrdenCompra");
                        db.AddInParameter(cmdDetalleOrdenA, "idBien", DbType.Int32);
                        db.AddInParameter(cmdDetalleOrdenA, "idOrdenCompra", DbType.Int32);
                        db.AddInParameter(cmdDetalleOrdenA, "cantidad", DbType.Decimal);

                        foreach (DetalleOrdenCompra d in ordenCompra.Detalle)
                        {
                            db.SetParameterValue(cmdDetalleOrdenA, "idBien", d.Bien.IdBien);
                            db.SetParameterValue(cmdDetalleOrdenA, "idOrdenCompra", idOrdenCompra);
                            db.SetParameterValue(cmdDetalleOrdenA, "cantidad", 0);
                            
                            result = db.ExecuteNonQuery(cmdDetalleOrdenA, transaction);
                            if (result == 0) throw new Exception("Error al Eliminar Detalle Antiguo de la Orden.");
                        }

                        // ACTUALIZAR ESTADO DE ATENCION DE ORDEN DE PEDIDO

                        DbCommand cmdOPedido = db.GetStoredProcCommand("UpdateEstadoOrdenPedido");

                        db.AddInParameter(cmdOPedido, "idOrdenCompra", DbType.Int32, ordenCompra.OrdenPedido.IdOrdenPedido);
                        db.AddInParameter(cmdOPedido, "estado", DbType.Boolean, false);
                        
                        result = db.ExecuteNonQuery(cmdOPedido, transaction);
                        if (result == 0) throw new Exception("Error al Actualizar Estado de Orden Pedido.");

                        // ELIMINAR ORDEN DE COMPRA

                        DbCommand cmdOrdenCompra = db.GetStoredProcCommand("DeleteOrdenCompra");

                        db.AddInParameter(cmdOrdenCompra, "idOrdenCompra", DbType.Int32, idOrdenCompra);

                        result = db.ExecuteNonQuery(cmdOrdenCompra, transaction);
                        if (result == 0) throw new Exception("Error al Eliminar Orden de Compra.");

                        transaction.Commit();
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        throw ex;
                    }
                }
            }
        }

        public List<int> ListarIDPorProveedor(int idProveedor)
        {
            List<int> ids = new List<int>();
            DbCommand command = db.GetStoredProcCommand("GetIdOrdenCompraByProveedor");
            db.AddInParameter(command, "idProveedor", DbType.Int32, idProveedor);
            using (IDataReader dr = db.ExecuteReader(command))
            {
                while (dr.Read())
                {
                    ids.Add(dr.GetInt32(dr.GetOrdinal("IdOrdenCompra")));
                }
            }
            return ids;
        }
    }
}
